package com.py.framework.controller;

import com.py.framework.common.Constants;
import com.py.framework.common.controller.SystemController;
import com.py.framework.core.common.Page;
import com.py.framework.core.exception.ServiceException;
import com.py.framework.core.helper.HttpServletHelper;
import com.py.framework.core.log.ExceptionLogger;
import com.py.framework.core.rest.support.RestServiceResult;
import com.py.framework.entity.AreaEntity;
import com.py.framework.entity.OfficeEntity;
import com.py.framework.entity.UserEntity;
import com.py.framework.service.AreaService;
import com.py.framework.service.AuthenticationService;
import com.py.framework.service.OfficeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 部门管理Controller
 *
 * @author Leegern
 * @date 2018年4月25日
 */
@Api(tags = "office", description = "部门管理")
@RestController
@RequestMapping("/office")
public class OfficeController extends SystemController {

    public static final String PERMISSION_DENIED = "你无此权限，不能使用此功能，请联系管理员";

    @Autowired
    private OfficeService officeService;

    @Autowired
    private AreaService areaService;

    @Autowired
    private AuthenticationService authenticationService;

    /**
     * @api {post} /office/addOfficeInfo.json 添加部门实体
     * @apiName addOfficeInfo
     * @apiVersion 0.0.1
     * @apiGroup 部门管理
     * @apiParam {OfficeEntity} entity
     * @apiParam {String} officeName 部门名称
     * @apiParam {String} officeCode 部门编码
     * @apiParam {long} parentId 父节点ID
     * @apiParam {long} areaId 区域ID
     * @apiParam {int} orderBy 排序
     * @apiParamExample {json} 请求参数示例
     * {"createTime":1531303130000,"updateTime":1531303130000,"delFlag":1,"officeName":"工商局","officeCode":"gsj","parentId":0,"areaId":2,"orderBy":1}
     * @apiSuccess {String} code 状态码:0 成功 -1 失败
     * @apiSuccess {String} msg 错误信息
     * @apiSuccess {int} count 结果集数据量
     * @apiSuccess {String} data 结果集
     * @apiSuccessExample {json} 成功返回结果
     * {"code":0,"msg":null,"count":0,"data":null}
     */
    @RequestMapping(value = "/addOfficeInfo", method = RequestMethod.POST)
    @ApiOperation(value = "添加部门", httpMethod = "POST", produces = "application/json")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "OfficeEntity", name = "entity", value = "部门信息实体", required = true)})
    public RestServiceResult<Object> addOfficeInfo(@RequestBody OfficeEntity entity, HttpServletRequest request) {
        RestServiceResult<Object> result = super.getSuccessRestServiceResult();
        if (null != entity) {
            try {
                // 获取当前用户信息
                UserEntity user = authenticationService.getCurrentUserInfo(HttpServletHelper.getUserToken(request));
                if (null != user && user.getId() > Constants.NUMBER_ZERO) {
                    int userType = user.getUserType();
                    if (1 == userType) {
                        // 普通用户无法创建部门
                        return super.getFailedRestServiceResult(PERMISSION_DENIED);
                    } else if (4 == userType) {
                        Map<String, Object> params = new HashMap<>(2);
                        params.put("officeId", entity.getParentId());
                        // 部门管理员用户
                        params.put("userOfficeId", user.getOfficeId());
                        params.put("areaId", entity.getAreaId());
                        int num = officeService.checkAddPermission(params);
                        if (num <= 0) {
                            return super.getFailedRestServiceResult(PERMISSION_DENIED);
                        }
                    } else if (2 == userType) {
                        // Map<String, Object> params = new HashMap<>(2);
                        // params.put("userAreaId", user.getAreaId());
                        // 区域管理员用户
                        // params.put("addAreaId", entity.getAreaId());
                        // int num = officeService.checkAddPermission(params);
                        // if (num <= 0) {
                        // return
                        // super.getFailedRestServiceResult(PERMISSION_DENIED);
                        // }
                        if (!hasAddPermission(user.getAreaId(), entity.getAreaId())) {
                            return super.getFailedRestServiceResult(PERMISSION_DENIED);
                        }
                    }
                }
                officeService.addOfficeInfo(entity);
            } catch (Exception e) {
                result = super.getFailedRestServiceResult("添加失败！");
                ExceptionLogger.error(e);
            }
        }
        return result;
    }

    private boolean hasAddPermission(long userAreaId, long addAreaId) {

        // 区域id相同或者存在父子关系

        if (userAreaId == addAreaId) {

            return true;
        }

        boolean hasPermisson = false;

        List<Long> ids = new ArrayList<Long>();
        ids.add(addAreaId);
        List<AreaEntity> areas = areaService.getAreasByIds(ids);
        if (areas != null && areas.size() > 0) {

            AreaEntity areaEntity = areas.get(0);

            String allParentId = areaEntity.getAllParentId();

            if (allParentId != null) {

                String[] split = allParentId.split(",");

                List<String> asList = Arrays.asList(split);

                if (asList.contains(String.valueOf(userAreaId))) {
                    hasPermisson = true;

                }

            }

        }

        return hasPermisson;

    }

    /**
     * @api {post} /office/queryOfficeForPage.json 分页查询部门列表
     * @apiName queryOfficeForPage
     * @apiVersion 0.0.1
     * @apiGroup 部门管理
     * @apiParam {int} page 当前页码
     * @apiParam {int} limit 每页条数
     * @apiParam {String} officeName 部门名称
     * @apiParam {String} officeCode 部门编码
     * @apiParam {long} officeId 部门Id
     * @apiParam {long} areaId 区域Id
     * @apiParamExample {json} 请求参数示例 {}
     * @apiSuccess {String} code 状态码:0 成功 -1 失败
     * @apiSuccess {String} msg 错误信息
     * @apiSuccess {int} count 结果集数据量
     * @apiSuccess {String} data 结果集
     * @apiSuccess {String} officeName 部门名称
     * @apiSuccess {String} officeCode 部门编码
     * @apiSuccess {long} parentId 父节点ID
     * @apiSuccess {long} areaId 区域ID
     * @apiSuccess {int} orderBy 排序
     * @apiSuccess {String} areaName 区域名称
     * @apiSuccess {String} parentOfficeName 父部门名称
     * @apiSuccessExample {json} 成功返回结果
     * {"code":0,"msg":null,"count":1,"data":[{"id":1,"createTime":1531303130000,"updateTime":1531303130000,"delFlag":1,"officeName":"工商局","officeCode":"gsj","parentId":0,"areaId":2,"orderBy":1,"areaName":"建邺区","parentOfficeName":null}]}
     */
    @RequestMapping(value = "/queryOfficeForPage", method = RequestMethod.POST)
    @ApiOperation(value = "分页查询部门列表", httpMethod = "POST", produces = "application/json")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "int", name = "page", value = "页码", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "int", name = "limit", value = "分页大小", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "officeName", value = "部门名称", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "officeCode", value = "部门编码", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "officeId", value = "部门ID", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "areaId", value = "区域ID", required = true)})
    public RestServiceResult<List<OfficeEntity>> queryOfficeForPage(int page, int limit, String officeName,
                                                                    String officeCode, @RequestParam(value = "officeId", required = false, defaultValue = "0") long officeId,
                                                                    @RequestParam(value = "areaId", required = false, defaultValue = "0") long areaId,
                                                                    HttpServletRequest request) {
        Map<String, Object> params = new HashMap<>();
        Page pager = super.getPage(page, limit);
        params.put("page", pager);
        params.put("officeName", officeName);
        params.put("officeCode", officeCode);
        params.put("officeId", officeId);
        params.put("areaId", areaId);
        String jdToken = HttpServletHelper.getUserToken(request);
        List<OfficeEntity> datas = Collections.emptyList();
        String roleName = "";
        // 用户信息
        try {
            // 获取当前用户信息
            UserEntity user = authenticationService.getCurrentUserInfo(jdToken);
            roleName= user.getRoleName();
            if (null != user && user.getId() > Constants.NUMBER_ZERO) {
                int userType = user.getUserType();
                if (!roleName.equals("系统管理员")) {
                    // 普通用户无法查看部门信息
                    return super.getPageSuccessRestServiceResult(pager.getTotalCount(), datas);
//                } else if (4 == userType) {
//                    // 部门管理员用户
//                    params.put("userOfficeId", user.getOfficeId());
//                } else if (2 == userType) {
//                    // 区域管理员用户
//                    params.put("userAreaId", user.getAreaId());
//                }
            }
            datas = officeService.queryOfficeForPage(params);
            }
        } catch (Exception e) {
            ExceptionLogger.error("OfficeController#queryOfficeForPage", "获取当前用户数据异常", e);
            return super.getPageSuccessRestServiceResult(pager.getTotalCount(), Collections.emptyList());
        }
        return super.getPageSuccessRestServiceResult(pager.getTotalCount(), datas);
    }

    /**
     * @api {post} /office/getOfficesByOfficeId.json 根据Id查询部门数据
     * @apiName getOfficesByOfficeId
     * @apiVersion 0.0.1
     * @apiGroup 部门管理
     * @apiParam {String} officeId 部门Id
     * @apiParamExample {json} 请求参数示例 {}
     * @apiSuccess {String} code 状态码:0 成功 -1 失败
     * @apiSuccess {String} msg 错误信息
     * @apiSuccess {int} count 结果集数据量
     * @apiSuccess {String} data 结果集
     * @apiSuccess {String} data 结果集
     * @apiSuccess {String} officeName 部门名称
     * @apiSuccess {String} officeCode 部门编码
     * @apiSuccess {long} parentId 父节点ID
     * @apiSuccess {long} areaId 区域ID
     * @apiSuccess {int} orderBy 排序
     * @apiSuccess {String} areaName 区域名称
     * @apiSuccess {String} parentOfficeName 父部门名称
     * @apiSuccessExample {json} 成功返回结果
     * {"code":0,"msg":null,"count":3,"data":[{"id":1,"createTime":1531303130000,"updateTime":1531303130000,"delFlag":1,"officeName":"工商局","officeCode":"gsj","parentId":0,"areaId":2,"orderBy":1,"areaName":"建邺区","parentOfficeName":null}]}
     */
    @RequestMapping(value = "/getOfficesByOfficeId", method = RequestMethod.POST)
    @ApiOperation(value = "根据Id查询部门数据", httpMethod = "POST", produces = "application/json")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "officeId", value = "部门ID", required = true)})
    public RestServiceResult<List<OfficeEntity>> getOfficesByOfficeId(String officeId) {
        List<OfficeEntity> datas = null;
        if (StringUtils.isNotBlank(officeId)) {
            datas = officeService.getOfficesByOfficeId(officeId);
        }
        return super.getSuccessRestServiceResult(datas);
    }

    /**
     * @api {post} /office/getAllOffices.json 获取所有部门数据
     * @apiName getAllOffices
     * @apiVersion 0.0.1
     * @apiGroup 部门管理
     * @apiParamExample {json} 请求参数示例 {}
     * @apiSuccess {String} code 状态码:0 成功 -1 失败
     * @apiSuccess {String} msg 错误信息
     * @apiSuccess {int} count 结果集数据量
     * @apiSuccess {String} data 结果集
     * @apiSuccess {String} officeName 部门名称
     * @apiSuccess {String} officeCode 部门编码
     * @apiSuccess {long} parentId 父节点ID
     * @apiSuccess {long} areaId 区域ID
     * @apiSuccess {int} orderBy 排序
     * @apiSuccess {String} areaName 区域名称
     * @apiSuccess {String} parentOfficeName 父部门名称
     * @apiSuccessExample {json} 成功返回结果
     * {"code":0,"msg":null,"count":1,"data":[{"id":1,"createTime":1531303130000,"updateTime":1531303130000,"delFlag":1,"officeName":"工商局","officeCode":"gsj","parentId":0,"areaId":2,"orderBy":1,"areaName":"建邺区","parentOfficeName":null}]}
     */
    @RequestMapping(value = "/getAllOffices", method = RequestMethod.POST)
    @ApiOperation(value = "获取所有部门数据", httpMethod = "POST", produces = "application/json")
    public RestServiceResult<List<OfficeEntity>> getAllOffices() {
        List<OfficeEntity> datas = officeService.getOfficesByOfficeId(null);
        return super.getSuccessRestServiceResult(datas);
    }

    @RequestMapping(value = "/getOfficesByAreaId", method = RequestMethod.POST)
    @ApiOperation(value = "获取区域部门数据", httpMethod = "POST", produces = "application/json")
    public RestServiceResult<List<OfficeEntity>> getOfficesByAreaId(@RequestParam(required = true) long areaId) {
        List<OfficeEntity> datas = officeService.getOfficesByAreaId(areaId);
        return super.getSuccessRestServiceResult(datas);
    }

    /**
     * @api {post} /office/findOneOffice.json 根据部门Id获取部门信息
     * @apiName findOneOffice
     * @apiVersion 0.0.1
     * @apiGroup 部门管理
     * @apiParam {long} id 部门Id
     * @apiParamExample {json} 请求参数示例 {}
     * @apiSuccess {String} code 状态码:0 成功 -1 失败
     * @apiSuccess {String} msg 错误信息
     * @apiSuccess {int} count 结果集数据量
     * @apiSuccess {String} data 结果集
     * @apiSuccess {String} officeName 部门名称
     * @apiSuccess {String} officeCode 部门编码
     * @apiSuccess {long} parentId 父节点ID
     * @apiSuccess {long} areaId 区域ID
     * @apiSuccess {int} orderBy 排序
     * @apiSuccess {String} areaName 区域名称
     * @apiSuccess {String} parentOfficeName 父部门名称
     * @apiSuccessExample {json} 成功返回结果
     * {"code":0,"msg":null,"count":1,"data":{"id":1,"createTime":1531303130000,"updateTime":1531303130000,"delFlag":1,"officeName":"工商局","officeCode":"gsj","parentId":0,"areaId":2,"orderBy":1,"areaName":"建邺区","parentOfficeName":null}}
     */
    @RequestMapping(value = "/findOneOffice", method = RequestMethod.POST)
    @ApiOperation(value = "根据部门Id获取部门信息", httpMethod = "POST", produces = "application/json")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "id", value = "部门ID", required = true)})
    public RestServiceResult<OfficeEntity> findOneOffice(long id) {
        OfficeEntity data = null;
        if (id > Constants.NUMBER_ZERO) {
            data = officeService.findOneOffice(id);
        }
        return super.getSuccessRestServiceResult(data);
    }

    /**
     * @api {post} /office/updateOffice.json 更新部门信息
     * @apiName updateOffice
     * @apiVersion 0.0.1
     * @apiGroup 部门管理
     * @apiParam {OfficeEntity} entity
     * @apiParam {long} id 部门Id
     * @apiParam {String} officeName 部门名称
     * @apiParam {String} officeCode 部门编码
     * @apiParam {long} parentId 父节点ID
     * @apiParam {long} areaId 区域ID
     * @apiParam {int} orderBy 排序
     * @apiParamExample {json} 请求参数示例 {}
     * @apiSuccess {String} code 状态码:0 成功 -1 失败
     * @apiSuccess {String} msg 错误信息
     * @apiSuccess {int} count 结果集数据量
     * @apiSuccess {String} data 结果集
     * @apiSuccessExample {json} 成功返回结果
     * {"code":0,"msg":null,"count":0,"data":null}
     */
    @RequestMapping(value = "/updateOffice", method = RequestMethod.POST)
    @ApiOperation(value = "更新部门信息", httpMethod = "POST", produces = "application/json")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "OfficeEntity", name = "entity", value = "部门信息实体", required = true)})
    public RestServiceResult<Object> updateOffice(@RequestBody OfficeEntity entity) {
        RestServiceResult<Object> result = super.getSuccessRestServiceResult();
        if (null != entity) {
            try {
                officeService.updateOffice(entity);
            } catch (Exception e) {
                result = super.getFailedRestServiceResult("更新失败！");
                ExceptionLogger.error(e);
            }
        }
        return result;
    }

    /**
     * @api {post} /office/batchDelOffice.json 批量删除部门
     * @apiName batchDelOffice
     * @apiVersion 0.0.1
     * @apiGroup 部门管理
     * @apiParam {String} ids 部门Id集合
     * @apiParamExample {json} 请求参数示例 {}
     * @apiSuccess {String} code 状态码:0 成功 -1 失败
     * @apiSuccess {String} msg 错误信息
     * @apiSuccess {int} count 结果集数据量
     * @apiSuccess {String} data 结果集
     * @apiSuccessExample {json} 成功返回结果
     * {"code":0,"msg":null,"count":0,"data":null}
     */
    @RequestMapping(value = "/batchDelOffice", method = RequestMethod.POST)
    @ApiOperation(value = "批量删除部门", httpMethod = "POST", produces = "application/json")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "ids", value = "部门Id集合", required = true)})
    public RestServiceResult<Object> batchDelOffice(String ids) {
        RestServiceResult<Object> result = super.getSuccessRestServiceResult();
        if (StringUtils.isNotBlank(ids)) {
            try {
                officeService.batchDelOffice(super.convert2Long(ids));
            } catch (ServiceException e) {
                result = super.getFailedRestServiceResult(e.getMessage());
                ExceptionLogger.error(e);
            } catch (Exception e) {
                result = super.getFailedRestServiceResult("删除失败！");
                ExceptionLogger.error(e);
            }
        }
        return result;
    }

    /**
     * @api {post} /office/isExistOffice.json 根据部门编码判断是否有重复数据
     * @apiName isExistOffice
     * @apiVersion 0.0.1
     * @apiGroup 部门管理
     * @apiParam {String} officeCode 部门编码
     * @apiParam {long} officeId 部门Id
     * @apiParamExample {json} 请求参数示例 {}
     * @apiSuccess {String} code 状态码:0 成功 -1 失败
     * @apiSuccess {String} msg 错误信息
     * @apiSuccess {int} count 结果集数据量
     * @apiSuccess {String} data 结果集
     * @apiSuccess {String} flag true 存在重复, false 不存在重复
     * @apiSuccessExample {json} 成功返回结果
     * {"code":0,"msg":null,"count":0,"data":{"flag",
     * "true"}}
     */
    @RequestMapping(value = "/isExistOffice", method = RequestMethod.POST)
    @ApiOperation(value = "根据部门编码判断是否有重复数据", httpMethod = "POST", produces = "application/json")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "officeCode", value = "部门编码", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "officeId", value = "部门Id", required = true)})
    public RestServiceResult<Map<String, String>> isExistOffice(String officeCode,
                                                                @RequestParam(value = "officeId", required = false, defaultValue = "0") long officeId) {
        RestServiceResult<Map<String, String>> rstData = null;
        Map<String, String> result = new HashMap<>();
        String flag = "";
        if (StringUtils.isNotBlank(officeCode)) {
            try {
                List<OfficeEntity> datas = officeService.getOfficesByCode(officeId, officeCode);
                if (!CollectionUtils.isEmpty(datas)) {
                    flag = "true";
                } else {
                    flag = "false";
                }
                result.put("flag", flag);
            } catch (Exception e) {
                rstData = super.getFailedRestServiceResult("查询失败！");
                ExceptionLogger.error(e);
            }
        }
        rstData = super.getSuccessRestServiceResult(result);
        return rstData;
    }

    /**
     * 一键生成部门token
     *
     * @return
     */
    @RequestMapping(value = "/generateOfficeToken", method = RequestMethod.POST)
    @ApiOperation(value = "一键生成部门token", httpMethod = "POST", produces = "application/json")
    public RestServiceResult<Object> updateOffice() {
        RestServiceResult<Object> result = super.getSuccessRestServiceResult();

        try {
            officeService.generateOfficeToken();
        } catch (Exception e) {
            result = super.getFailedRestServiceResult("操作失败！");
            ExceptionLogger.error(e);
        }

        return result;
    }

    /**
     * 查询已删除的部门
     *
     * @author YaoS
     * @date 19/5/27 14:38
     */
    @RequestMapping(value = "/deleteDept")
    public RestServiceResult<List<String>> deleteDept() {
        List<String> ids;
        try {
            ids = officeService.deleteDept();
        } catch (Exception e) {
            ExceptionLogger.error(e);
            return super.getFailedRestServiceResult("查询已删除的部门失败！");
        }
        return super.getSuccessRestServiceResult(ids);
    }
    
    /**
     * 根据名称查询部门id
     * @param deptName
     * @return
     */
    @RequestMapping(value = "/getDeptIdByName.json")
    public RestServiceResult<Long> getDeptIdByName(String deptName) {
    	RestServiceResult<Long> result = super.getSuccessRestServiceResult();
    	
    	if(StringUtils.isEmpty(deptName)) {
    		result.setData(null);
    		result.setCode(RestServiceResult.CODE_UNKNOW);
    		result.setMsg("部门名称不能为空！");
    		return result;
    	}
    	Long deptId = 0L;
        try {
            deptId = officeService.getDeptIdByName(deptName);
        } catch (Exception e) {
            ExceptionLogger.error(e);
            return super.getFailedRestServiceResult("查询部门id失败！");
        }
        return super.getSuccessRestServiceResult(deptId);
    }
}